package com.kakarote.hrm.cron;

import cn.hutool.core.collection.CollUtil;
import cn.hutool.core.convert.Convert;
import cn.hutool.core.date.LocalDateTimeUtil;
import cn.hutool.core.util.ObjectUtil;
import cn.hutool.core.util.StrUtil;
import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
import com.kakarote.hrm.constant.*;
import com.kakarote.hrm.entity.PO.*;
import com.kakarote.hrm.mapper.HrmDeptMapper;
import com.kakarote.hrm.mapper.HrmEmployeeDataMapper;
import com.kakarote.hrm.mapper.HrmEmployeeFieldMapper;
import com.kakarote.hrm.service.IHrmAttendanceGroupService;
import com.kakarote.hrm.service.IHrmEmployeeChangeRecordService;
import com.kakarote.hrm.service.IHrmEmployeeQuitInfoService;
import com.kakarote.hrm.service.IHrmEmployeeService;
import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Component;

import java.time.LocalDateTime;
import java.util.ArrayList;
import java.util.List;
import java.util.stream.Collectors;

@Component
@Slf4j
public class EmployeeChangeCron {

    @Autowired
    private IHrmEmployeeChangeRecordService changeRecordService;

    @Autowired
    private IHrmEmployeeService employeeService;

    @Autowired
    private IHrmEmployeeQuitInfoService quitInfoService;

    @Autowired
    private IHrmAttendanceGroupService attendanceGroupService;

    @Autowired
    private HrmEmployeeDataMapper hrmEmployeeDataMapper;

    @Autowired
    private HrmEmployeeFieldMapper hrmEmployeeFieldMapper;

    @Autowired
    private HrmDeptMapper hrmDeptMapper;


    /**
     * 调岗晋升转正
     *
     */
    public void employeeChangeRecords() {
        List<HrmEmployee> employeeList = new ArrayList<>();
        List<HrmEmployeeChangeRecord> hrmEmployeeChangeRecords = changeRecordService.lambdaQuery()
                .groupBy(HrmEmployeeChangeRecord::getEmployeeId)
                .having("max(create_time)").list();
        hrmEmployeeChangeRecords.forEach(changeRecord -> {
            employeeList.add(employeeChangeRecord(changeRecord));
            if (changeRecord.getNewDept() != null) {
                changeDept(changeRecord,"dept");
            }
            if (StrUtil.isNotBlank(changeRecord.getNewPost())) {
                changeJobTitle(changeRecord,"job_title");
            }
            if (StrUtil.isNotBlank(changeRecord.getNewPostLevel())) {
                changeJobLevel(changeRecord,"job_level");
            }
        });
        List<HrmEmployee> list = employeeService.lambdaQuery()
                .ne(HrmEmployee::getStatus, EmployeeStatusEnum.OFFICIAL.getValue())
                .apply("to_days(become_time) = to_days(now())")
                .list();
        list.forEach(employee -> {
            employee.setBecomeTime(LocalDateTime.now().toLocalDate());
            employee.setStatus(EmployeeStatusEnum.OFFICIAL.getValue());
            employee.setUpdateTime(LocalDateTime.now());
        });
        employeeList.addAll(list);
        if (CollUtil.isNotEmpty(employeeList)) {
            employeeService.saveOrUpdateBatch(employeeList);
        }
    }

    /**
     * 员工离职变更状态
     *
     * @param companyId
     */
    public void employeeQuit() {
        List<HrmEmployeeQuitInfo> quitInfoList = quitInfoService.lambdaQuery().select(HrmEmployeeQuitInfo::getEmployeeId)
                .apply("to_days(plan_quit_time) = to_days(now())").list();
        List<HrmEmployee> employeeList = quitInfoList.stream().map(quitInfo -> {
            HrmEmployee employee = employeeService.queryById(quitInfo.getEmployeeId());
            employee.setEntryStatus(EmployeeEntryStatusEnum.已离职.getValue());
            if (ObjectUtil.isNotNull(employee.getCompanyAgeStartTime())) {
                long nowCompanyAge = LocalDateTimeUtil.between(employee.getCompanyAgeStartTime().atStartOfDay(), LocalDateTime.now()).toDays() + 1;
                if (LocalDateTimeUtil.toEpochMilli(employee.getCompanyAgeStartTime()) > System.currentTimeMillis()) {
                    nowCompanyAge = 0;
                }
                employee.setCompanyAge(Convert.toInt(nowCompanyAge));
            }
            return employee;
        }).collect(Collectors.toList());
        if (CollUtil.isNotEmpty(employeeList)) {
            employeeService.saveOrUpdateBatch(employeeList);
        }
    }

    public static HrmEmployee employeeChangeRecord(HrmEmployeeChangeRecord changeRecord) {
        Integer changeType = changeRecord.getChangeType();
        HrmEmployee employee = new HrmEmployee();
        employee.setEmployeeId(changeRecord.getEmployeeId());
        employee.setDeptId(changeRecord.getNewDept());
        employee.setOrgId(changeRecord.getNewOrg());
        employee.setPost(changeRecord.getNewPost());
        employee.setPostLevel(changeRecord.getNewPostLevel());
        if (changeType.equals(HrmActionBehaviorEnum.CHANGE_POST.getValue())
                || changeType.equals(HrmActionBehaviorEnum.PROMOTED.getValue())
                || changeType.equals(HrmActionBehaviorEnum.DEGRADE.getValue())
                || changeType.equals(HrmActionBehaviorEnum.CHANGE_FULL_TIME_EMPLOYEE.getValue())) {
            employee.setWorkAddress(changeRecord.getNewWorkAddress());
            if (changeType.equals(HrmActionBehaviorEnum.CHANGE_FULL_TIME_EMPLOYEE.getValue())) {
                Integer probation = changeRecord.getProbation();
                employee.setProbation(probation);
                if (probation == 0) {
                    employee.setBecomeTime(LocalDateTime.now().toLocalDate());
                    employee.setStatus(EmployeeStatusEnum.OFFICIAL.getValue());
                } else {
                    employee.setStatus(EmployeeStatusEnum.TRY_OUT.getValue());
                }
            }
        } else if (changeType.equals(HrmActionBehaviorEnum.BECOME.getValue())) {
            employee.setBecomeTime(LocalDateTime.now().toLocalDate());
            employee.setStatus(EmployeeStatusEnum.OFFICIAL.getValue());
        }
        employee.setUpdateTime(LocalDateTime.now());
        return employee;
    }

    public void changeAttendanceGroup() {
        //查询出所有的员工,为之前未设置过考勤时间设置出勤班次
        attendanceGroupService.setAttendanceDateShiftByGroup();
        //查询出所有生效的考勤组
        List<HrmAttendanceGroup> hrmAttendanceGroupList = attendanceGroupService.lambdaQuery()
                .eq(HrmAttendanceGroup::getOldSetting, IsEnum.NO.getValue()).apply("to_days(effect_time) = to_days(now())").list();
        if (CollUtil.isNotEmpty(hrmAttendanceGroupList)) {
            hrmAttendanceGroupList.forEach(hrmAttendanceGroup -> {
                attendanceGroupService.changeAttendanceGroup(hrmAttendanceGroup);
            });
        }
    }


    private void changeJobLevel(HrmEmployeeChangeRecord hrmEmployeeChangeRecord, String fieldName) {
        LambdaQueryWrapper<HrmEmployeeField> hrmEmployeeFieldLambdaQueryWrapper = new LambdaQueryWrapper<>();
        hrmEmployeeFieldLambdaQueryWrapper.eq(HrmEmployeeField::getFieldName, fieldName);
        HrmEmployeeField hrmEmployeeField = hrmEmployeeFieldMapper.selectOne(hrmEmployeeFieldLambdaQueryWrapper);
        if (null != hrmEmployeeField) {
            LambdaQueryWrapper<HrmEmployeeData> hrmEmployeeDataLambdaQueryWrapper = new LambdaQueryWrapper<>();
            hrmEmployeeDataLambdaQueryWrapper.eq(HrmEmployeeData::getFieldId, hrmEmployeeField.getFieldId());
            hrmEmployeeDataLambdaQueryWrapper.eq(HrmEmployeeData::getEmployeeId, hrmEmployeeChangeRecord.getEmployeeId());
            hrmEmployeeDataMapper.delete(hrmEmployeeDataLambdaQueryWrapper);
            HrmEmployeeData hrmEmployeeData = new HrmEmployeeData();
            hrmEmployeeData.setFieldId(hrmEmployeeField.getFieldId());
            hrmEmployeeData.setLabelGroup(LabelGroupEnum.POST.getValue());
            hrmEmployeeData.setName(hrmEmployeeField.getName());
            hrmEmployeeData.setFieldValue(String.valueOf(hrmEmployeeChangeRecord.getNewPostLevel()));
            hrmEmployeeData.setFieldValueDesc(String.valueOf(hrmEmployeeChangeRecord.getNewPostLevel()));
            hrmEmployeeData.setEmployeeId((hrmEmployeeChangeRecord.getEmployeeId()));
            hrmEmployeeDataMapper.insert(hrmEmployeeData);
        }
    }

    private void changeJobTitle(HrmEmployeeChangeRecord hrmEmployeeChangeRecord, String fieldName) {
        LambdaQueryWrapper<HrmEmployeeField> hrmEmployeeFieldLambdaQueryWrapper = new LambdaQueryWrapper<>();
        hrmEmployeeFieldLambdaQueryWrapper.eq(HrmEmployeeField::getFieldName, fieldName);
        HrmEmployeeField hrmEmployeeField = hrmEmployeeFieldMapper.selectOne(hrmEmployeeFieldLambdaQueryWrapper);
        if (null != hrmEmployeeField) {
            LambdaQueryWrapper<HrmEmployeeData> hrmEmployeeDataLambdaQueryWrapper = new LambdaQueryWrapper<>();
            hrmEmployeeDataLambdaQueryWrapper.eq(HrmEmployeeData::getFieldId, hrmEmployeeField.getFieldId());
            hrmEmployeeDataLambdaQueryWrapper.eq(HrmEmployeeData::getEmployeeId, hrmEmployeeChangeRecord.getEmployeeId());
            hrmEmployeeDataMapper.delete(hrmEmployeeDataLambdaQueryWrapper);
            HrmEmployeeData hrmEmployeeData = new HrmEmployeeData();
            hrmEmployeeData.setFieldId(hrmEmployeeField.getFieldId());
            hrmEmployeeData.setLabelGroup(LabelGroupEnum.POST.getValue());
            hrmEmployeeData.setName(hrmEmployeeField.getName());
            hrmEmployeeData.setFieldValue(String.valueOf(hrmEmployeeChangeRecord.getNewPost()));
            hrmEmployeeData.setFieldValueDesc(String.valueOf(hrmEmployeeChangeRecord.getNewPost()));
            hrmEmployeeData.setEmployeeId((hrmEmployeeChangeRecord.getEmployeeId()));
            hrmEmployeeDataMapper.insert(hrmEmployeeData);
        }
    }
    private void changeDept(HrmEmployeeChangeRecord hrmEmployeeChangeRecord, String fieldName) {
        // 校验更改的是部门还是机构
        HrmDept hrmDept = hrmDeptMapper.selectById(hrmEmployeeChangeRecord.getNewDept());
        if (null == hrmDept) {
            return;
        }
        LambdaQueryWrapper<HrmEmployeeField> hrmEmployeeFieldLambdaQueryWrapper = new LambdaQueryWrapper<>();
        hrmEmployeeFieldLambdaQueryWrapper.eq(HrmEmployeeField::getFieldName, fieldName);
        HrmEmployeeField hrmEmployeeField = hrmEmployeeFieldMapper.selectOne(hrmEmployeeFieldLambdaQueryWrapper);
        if (null != hrmEmployeeField) {
            LambdaQueryWrapper<HrmEmployeeData> hrmEmployeeDataLambdaQueryWrapper = new LambdaQueryWrapper<>();
            hrmEmployeeDataLambdaQueryWrapper.eq(HrmEmployeeData::getFieldId, hrmEmployeeField.getFieldId());
            hrmEmployeeDataLambdaQueryWrapper.eq(HrmEmployeeData::getEmployeeId, hrmEmployeeChangeRecord.getEmployeeId());
            hrmEmployeeDataMapper.delete(hrmEmployeeDataLambdaQueryWrapper);
            HrmEmployeeData hrmEmployeeData = new HrmEmployeeData();
            hrmEmployeeData.setFieldId(hrmEmployeeField.getFieldId());
            hrmEmployeeData.setLabelGroup(LabelGroupEnum.POST.getValue());
            hrmEmployeeData.setName(hrmEmployeeField.getName());
            hrmEmployeeData.setFieldValue(String.valueOf(hrmEmployeeChangeRecord.getNewDept()));
            hrmEmployeeData.setFieldValueDesc(String.valueOf(hrmEmployeeChangeRecord.getNewDept()));
            hrmEmployeeData.setEmployeeId((hrmEmployeeChangeRecord.getEmployeeId()));
            hrmEmployeeDataMapper.insert(hrmEmployeeData);
        }
        if (hrmDept.getDeptType() == 2) {
            HrmEmployeeField employeeField = hrmEmployeeFieldMapper.selectOne(new LambdaQueryWrapper<HrmEmployeeField>().eq(HrmEmployeeField::getFieldName, "org"));
            if (null != employeeField) {
                LambdaQueryWrapper<HrmEmployeeData> hrmEmployeeDataLambdaQueryWrapper = new LambdaQueryWrapper<>();
                hrmEmployeeDataLambdaQueryWrapper.eq(HrmEmployeeData::getFieldId, employeeField.getFieldId());
                hrmEmployeeDataLambdaQueryWrapper.eq(HrmEmployeeData::getEmployeeId, hrmEmployeeChangeRecord.getEmployeeId());
                hrmEmployeeDataMapper.delete(hrmEmployeeDataLambdaQueryWrapper);
                HrmEmployeeData hrmEmployeeData = new HrmEmployeeData();
                hrmEmployeeData.setFieldId(employeeField.getFieldId());
                hrmEmployeeData.setLabelGroup(LabelGroupEnum.POST.getValue());
                hrmEmployeeData.setName(employeeField.getName());
                hrmEmployeeData.setFieldValue(String.valueOf(hrmDept.getParentId()));
                hrmEmployeeData.setFieldValueDesc(String.valueOf(hrmDept.getParentId()));
                hrmEmployeeData.setEmployeeId((hrmEmployeeChangeRecord.getEmployeeId()));
                hrmEmployeeDataMapper.insert(hrmEmployeeData);
            }
        }
    }


}
